package org.jiucheng.magpiebridge.server.aio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jiucheng.magpiebridge.server.aio.proxy.ProxyClientWriteAttachment;

/**
 * Client附件
 * 
 * @author jiucheng
 *
 */
public class ClientAttachment {
    // 当前在写
    public final AtomicBoolean writed = new AtomicBoolean(false);
    
    // 代理服务
    private List<AsynchronousServerSocketChannel> asynchronousServerSocketChannels = new ArrayList<AsynchronousServerSocketChannel>();
    // 代理连接
    private final ConcurrentMap<Integer, ProxyClientWriteAttachment> proxys = new ConcurrentHashMap<Integer, ProxyClientWriteAttachment>();
    
    // Client连接
    AsynchronousSocketChannel asynchronousSocketChannel;
    // Client读入数据
    ByteBuffer readBuffer;
    
    public ClientAttachment(AsynchronousSocketChannel asynchronousSocketChannel) {
        this.asynchronousSocketChannel = asynchronousSocketChannel;
    }
    
    public ByteBuffer getReadBuffer() {
        return readBuffer;
    }
    
    public ClientAttachment setReadBuffer(ByteBuffer readBuffer) {
        this.readBuffer = readBuffer;
        return this;
    }
    
    public AsynchronousSocketChannel getAsynchronousSocketChannel() {
        return asynchronousSocketChannel;
    }

    public void putProxy(Integer uri, ProxyClientWriteAttachment proxy) {
        proxys.put(uri, proxy);
    }
    
    public ProxyClientWriteAttachment getProxy(Integer uri) {
        return proxys.get(uri);
    }
    
    public ProxyClientWriteAttachment removeProxy(Integer uri) {
        return proxys.remove(uri);
    }
    
    public void addProxyServer(AsynchronousServerSocketChannel asynchronousServerSocketChannel) {
        asynchronousServerSocketChannels.add(asynchronousServerSocketChannel);
    }
    
    public void close() {
        Set<Integer> keys = proxys.keySet();
        for (Integer key : keys) {
            ProxyClientWriteAttachment proxyWriteAttachment = proxys.remove(key);
            if (proxyWriteAttachment != null && proxyWriteAttachment.getAsynchronousSocketChannel() != null) {
                try {
                    proxyWriteAttachment.getAsynchronousSocketChannel().close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        for (AsynchronousServerSocketChannel asynchronousServerSocketChannel : asynchronousServerSocketChannels) {
            if (asynchronousServerSocketChannel != null) {
                try {
                    asynchronousServerSocketChannel.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if (asynchronousSocketChannel != null) {
            try {
                asynchronousSocketChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
